#include <QStringList>
#include <QRegExp>
#include "oxford-parser.h"
#include "oxford-word.h"

using namespace Oxford;

Parser::Parser()
{
}

Word Parser::parse(const QString &wordInfo)
{
    Word word;
    word._word = _findItem(wordInfo, "<span class=\"z_core_h\">([^<]+)</span>");

    word._is3000 = _itemExists(wordInfo, "coresym.gif");
    word._isAcademic = _itemExists(wordInfo, "mid-academic.gif");

    word._speechPart = _findItem(wordInfo, "<span class=\"pos\">([^<]+)</span>");

    word._gbTranscription = "Encoding bug: " + _findItem(wordInfo, "<img src=\"/external/images/pron-uk\\.gif\" alt=\"[^\"]+\" title=\"[^\"]+\" class=\"[^\"]+\" style=\"[^\"]+\" onclick=\"[^\"]+\" valign=\"[^\"]+\"/>([^<]+)</span>");
    word._gbPronunciation = _findItem(wordInfo, "<img src=\"/external/images/pron-uk\\.gif\" alt=\"[^\"]+\" title=\"[^\"]+\" class=\"[^\"]+\" style=\"[^\"]+\" onclick=\"playSoundFromFlash\\('([^']+)'");
    word._usTranscription = "Encoding bug: " + _findItem(wordInfo, "<img src=\"/external/images/pron-us\\.gif\" alt=\"[^\"]+\" title=\"[^\"]+\" class=\"[^\"]+\" style=\"[^\"]+\" onclick=\"[^\"]+\" valign=\"[^\"]+\"/>([^<]+)</span>");
    word._usPronunciation = _findItem(wordInfo, "<img src=\"/external/images/pron-us\\.gif\" alt=\"[^\"]+\" title=\"[^\"]+\" class=\"[^\"]+\" style=\"[^\"]+\" onclick=\"playSoundFromFlash\\('([^']+)'");

    QStringList usageVariants = _findItems(wordInfo, "<span class=\"z_n\">(.+[^>]</span></span>)</span>((<sp)|(</di))");
    for (QStringList::const_iterator variant = usageVariants.constBegin(); variant != usageVariants.constEnd(); variant++)
    {
        WordUsageVariant usage;
        usage._wordUsage = _findItem(*variant, "</span><span class=\"cf\">([^<]+)</span>");
        usage._usageRule = _findItem(*variant, "<span class=\"u?d\">([^<]+)</?span");
        usage._synonym = _findItem(*variant, "<span class=\"z_xh_eb\">([^<]+)</span>");

        QStringList usageExamples = _findItems(*variant, "(<span class=\"x-g\">.*</span>)</span>");
        for (QStringList::const_iterator usageExample = usageExamples.constBegin(); usageExample != usageExamples.constEnd(); usageExample++)
        {
            WordUsageExample example;
            example._wordUsage = _findItem(*usageExample, "<span class=\"x-g\"><span class=\"cf\">([^<]+)</span>");
            example._sentence = _findItem(*usageExample, "<span class=\"x\" id=\"[^\"]+\">(.*)</span>");
            example._clarification = _findItem(*usageExample, "<span class=\"gl\">(.*)</span>");

            usage._examples << example;
        }

        word._variants << usage;
    }
    return word;
}

QString Parser::_findItem(const QString &wordInfo, const QString &itemTemplate)
{
    QRegExp rx(itemTemplate);
    rx.setMinimal(true);

    QRegExp rx2("<[^>]+>");
    rx.setMinimal(true);
    return wordInfo.contains(rx) ? rx.cap(1).remove(rx2) : QString();
}

QStringList Parser::_findItems(const QString &wordInfo, const QString &itemTemplate)
{
    QRegExp rx(itemTemplate);
    rx.setMinimal(true);

    QStringList result;
    int pos = 0;
    while ((pos = rx.indexIn(wordInfo, pos)) != -1)
    {
        result << rx.cap(1);
        pos += rx.matchedLength();
    }

    return result;
}

bool Parser::_itemExists(const QString &wordInfo, const QString &itemTemplate)
{
    QRegExp rx(itemTemplate);

    return wordInfo.contains(rx);
}
